package com.boco.fc.auto.deploy;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.jdom.input.SAXBuilder;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 * 读取配置文件
 * @author yangfeng
 *
 */
public class XmlUtil {
	
	private Logger log = Logger.getLogger(this.getClass());
	
	/**
	 * 使用jdom解析xml文件
	 * @param xmlPath 配置文件路径
	 * @return
	 */
	public Map<String ,Map<String, Object>> parser(String xmlPath){
		log.info("读取配置文件：" + xmlPath);
		Map<String ,Map<String, Object>> serverMap = new HashMap<String ,Map<String, Object>>();
		
		try {
			SAXBuilder saxbuild = new SAXBuilder();
			org.jdom.Document doc;
			doc = saxbuild.build(xmlPath);
			Element element = doc.getRootElement();
			Element servers = (Element) element.getChildren().get(0);
			List<?> list = servers.getChildren();
			for (int i = 0; i < list.size(); i++) {
				Map<String, Object> server = new HashMap<String, Object>();
				Element e = (Element) list.get(i);
				log.info("读取配置:" + e.getChildText("host"));
				server.put("host", getXmlContent(e.getChildText("host"),""));
				server.put("port", getXmlContent(e.getChildText("port"),""));
				server.put("userName", getXmlContent(e.getChildText("userName"),""));
				server.put("password", getXmlContent(e.getChildText("password"),""));
				server.put("uploads", getUploadInfo(e.getChild("uploads")));
				server.put("commands", getCommandsList(e.getChild("commands")));
				serverMap.put((String) server.get("host"),server);
			}
		} catch (JDOMException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		}
		log.info("读取配置文件完成" + xmlPath);
		return serverMap;
	}
	
	/**
	 * 使用jdom解析xml文件
	 * @param xmlPath 配置文件路径
	 * @return
	 */
	public List<Map<String, Object>> parseJdom(String xmlPath){
		log.info("读取配置文件：" + xmlPath);
		List<Map<String, Object>> serverList = new ArrayList<Map<String, Object>>();
		
		try {
			SAXBuilder saxbuild = new SAXBuilder();
			org.jdom.Document doc;
			doc = saxbuild.build(xmlPath);
			Element element = doc.getRootElement();
			Element servers = (Element) element.getChildren().get(0);
			List<?> list = servers.getChildren();
			for (int i = 0; i < list.size(); i++) {
				Map<String, Object> serverMap = new HashMap<String, Object>();
				Element e = (Element) list.get(i);
				log.info("读取配置:" + e.getChildText("host"));
				serverMap.put("host", getXmlContent(e.getChildText("host"),""));
				serverMap.put("port", getXmlContent(e.getChildText("port"),""));
				serverMap.put("userName", getXmlContent(e.getChildText("userName"),""));
				serverMap.put("password", getXmlContent(e.getChildText("password"),""));
				serverMap.put("uploads", getUploadInfo(e.getChild("uploads")));
				serverMap.put("commands", getCommandsList(e.getChild("commands")));
				serverList.add(serverMap);
			}
		} catch (JDOMException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		}
		log.info("读取配置文件完成" + xmlPath);
		return serverList;
	}
	
	/**
	 * 处理路径配置
	 * @param content
	 * @param type
	 * @return
	 */
	private String getXmlContent(String content,String type){
		if(content!=null){
			content = content.trim();
			if(type!=null && "path".equals(type)){
				if(!content.endsWith(File.separator)){ //path以/结尾
					content = content + File.separator;
				}
			}
		}else{
			content = "";
		}
		return content;
	}

	/**
	 * jdom获取commands配置
	 * @param commands
	 * @return
	 */
	private List<String> getCommandsList(Element commands) {
		log.info("读取commands配置");
		List<String> lists = new ArrayList<String>();
		List<?> list = commands.getChildren();
		for (int i = 0; i < list.size(); i++) {
			Element e = (Element) list.get(i);
			lists.add(e.getText());
		}
		log.debug(lists.toString());
		return lists;
	}

	/**
	 * jdom获取uploads配置
	 * @param uploads
	 * @return
	 */
	private List<Map<String, String>> getUploadInfo(Element uploads) {
		log.info("读取uploads配置");
		List<Map<String, String>> lists = new ArrayList<Map<String, String>>();
		List<?> list = uploads.getChildren();
		for (int i = 0; i < list.size(); i++) {
			Map<String, String> node = new HashMap<String, String>();
			Element e = (Element) list.get(i);
			node.put("fileMode",e.getChild("localFile").getAttributeValue("fileMode"));
			node.put("localFile",getXmlContent(e.getChildText("localFile"),""));
			node.put("localPath","");
			node.put("localRoot",getXmlContent(e.getChildText("localPath"),"path"));
			node.put("remotePath",getXmlContent(e.getChildText("remotePath"),"path"));
			lists.add(node);
		}
		log.debug(lists.toString());
		return lists;
	}

	/**
	 * 使用JDK自带的javax.xml.parsers.DocumentBuilder解析xml
	 * @param xmlPath 配置文件路径
	 * @return
	 */
	public List<Map<String, Object>> parse(String xmlPath){
		log.info("读取配置文件：" + xmlPath);
		List<Map<String, Object>> serverList = new ArrayList<Map<String, Object>>();
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db;
		try {
			db = dbf.newDocumentBuilder();
			org.w3c.dom.Document document = db.parse(xmlPath);

			NodeList servers = document.getElementsByTagName("server");

			for (int i = 0; i < servers.getLength(); i++) {
				Map<String, Object> serverMap = new HashMap<String, Object>();
				NodeList server = servers.item(i).getChildNodes();
				for (int j = 0; j < server.getLength(); j++) {
					Node ns = server.item(j);
					if (ns.getNodeType() == 1) {
						if (ns.getNodeName().equals("host")) {
							log.info("读取server配置：" + ns.getTextContent());
							serverMap.put("host", ns.getTextContent());
						} else if (ns.getNodeName().equals("userName")) {
							serverMap.put("userName", ns.getTextContent());
						} else if (ns.getNodeName().equals("password")) {
							serverMap.put("password", ns.getTextContent());
						} else if (ns.getNodeName().equals("uploads")) {
							serverMap.put("uploads", getUploadInfo(ns));
						} else if (ns.getNodeName().equals("commands")) {
							serverMap.put("commands", getCommandsList(ns));
						}
					}
				}
				serverList.add(serverMap);
			}
		} catch (ParserConfigurationException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		} catch (SAXException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			log.error("解析配置文件错误：" + e.getMessage());
			e.printStackTrace();
		}
		log.info("读取配置文件完成" + xmlPath);
		return serverList;
	}

	/**
	 * 使用JDK自带的javax.xml.parsers.DocumentBuilder解析xml,获取commands配置
	 * @param commands
	 * @return
	 */
	private List<String> getCommandsList(Node commands) {
		log.info("读取commands配置");
		List<String> list = new ArrayList<String>();
		NodeList nodeList = commands.getChildNodes();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node up = nodeList.item(i);
			if (up.getNodeType() == 1) {
				if (up.getNodeName().equals("command")) {
					list.add(up.getTextContent());
				}
			}
		}
		log.debug(list.toString());
		return list;
	}

	/**
	 * /**
	 * 使用JDK自带的javax.xml.parsers.DocumentBuilder解析xml,获取uploads配置
	 * @param commands
	 * @return
	 */
	private List<Map<String, String>> getUploadInfo(Node uploads) {
		log.info("读取uploads配置");
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		NodeList uploadlistUp = uploads.getChildNodes();
		for (int k = 0; k < uploadlistUp.getLength(); k++) {
			Map<String, String> node = new HashMap<String, String>();
			Node n = uploadlistUp.item(k);

			if ((n.getNodeType() == 1) && (n.getNodeName().equals("upload"))) {
				NodeList uploadlist = n.getChildNodes();
				for (int i = 0; i < uploadlist.getLength(); i++) {
					Node up = uploadlist.item(i);
					if (up.getNodeType() == 1) {
						if (up.getNodeName().equals("localFile")) {
							node.put("fileMode", up.getAttributes().getNamedItem("fileMode").getTextContent());
							node.put("localFile", up.getTextContent());
						} else if (up.getNodeName().equals("localPath")) {
							node.put("localRoot", getXmlContent(up.getTextContent(),"path"));
							node.put("localPath", "");
						} else if (up.getNodeName().equals("remotePath")) {
							node.put("remotePath", getXmlContent(up.getTextContent(),"path"));
						}
					}
				}
				list.add(node);
			}
		}
		log.debug(list.toString());
		return list;
	}
}
